package apiCode;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Properties;

import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;

public class Source {
	SVNURL url;
	SVNRepository repository;
    ISVNEditor editor = null;
	ISVNAuthenticationManager authManager;

	public Source(){
			System.out.println("New Source");
	}

	/*
	 * Method to read config properties and user values to 
	 * connect and log in to the repository
	 */
	public void login() {

		System.out.println("** LOGIN ** ");

		// Read config properties file.
        Properties properties = new Properties();
        String configFile = "config.properties";

        InputStream inputStream;
		try {
			inputStream = new FileInputStream(configFile);
			
	        System.out.println("load properties with config");
	        properties.load(inputStream);

		} catch (FileNotFoundException e) {
			System.out.println("** LOGIN ERROR config file not found ** ");
			e.printStackTrace();
		} catch (IOException e) {
			
			System.out.println("** LOGIN ERROR  ** ");

			e.printStackTrace();
		}


        // get the property value and print it out
        System.out.println("Assign Properties values");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        String repourl = properties.getProperty("repourl");
        
		System.out.println(properties.getProperty("username"));
		System.out.println(properties.getProperty("password"));
		System.out.println(properties.getProperty("repourl"));
				
		// Repository will be accessed using the WebDav protocol https
		DAVRepositoryFactory.setup();
		
		// Implement the authentication manager interface with username password
		// see http://wiki.svnkit.com/Authentication
		authManager = new BasicAuthenticationManager(username,password);
		System.out.println("Authentication completed");
				
		
		try {
			this.url = SVNURL.parseURIEncoded(repourl);
			repository = SVNRepositoryFactory.create( this.url);

			//Create repository driver to bind to defined repository location
			System.out.println("URL "+url);
			System.out.println("Repository set");

			System.out.println( "Repository Root: " + repository.getRepositoryRoot( true ) );
			System.out.println( "Repository UUID: " + repository.getRepositoryUUID( true ) );

		} catch (SVNException e) {
			e.printStackTrace();
		}
		
        //Set an auth manager which will provide user credentials
        repository.setAuthenticationManager(authManager);  

        System.out.println("After setting auth manager");

	}
		
	/*
	 * Check out application's server repository
	 */
	public void checkOut() throws SVNException{
		
		System.out.println("Start checkOut()");

		// Repository revision
        long latestRepoRev = 0;
        
		try {
			latestRepoRev = repository.getLatestRevision();
		
			System.out.println("latest revision is "+latestRepoRev);            
        
			// Define comment for checkout
			String logMessage = "API Checking out File";
        
			// Set editor
			System.out.println("setting Editor");
			editor = repository.
						getCommitEditor( logMessage , null /*locks*/ , true /*keepLocks*/ , new CommitMediator() /*mediator to hold temp deltas*/ );
        
			// Open version of directory            
			System.out.println("Open root");
			editor.openRoot(latestRepoRev);
			
		} catch (SVNException e) {
			
			e.printStackTrace();
		}
		
        System.out.println("End checkOut()");
	}
	
	/*
	 * Commit changes to new file
	 */
	public void commit(String filename){
		
        System.out.println("Enter commit()");
                
		try {
			
			filename = "https://my-msc-project-2013.googlecode.com/svn/svnProject2014/src/Output/WorldCupTest11.xml";
           	editor.addFile( filename , null , -1 );			

	        // send delta to editor
	        SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator();

	        byte[] newData = "Testing Adding File v11 \n".getBytes();

	        System.out.println("Generating check Sum");
	        
	        // Generate checksum
	        String checksum = deltaGenerator.
					sendDelta(filename, new ByteArrayInputStream(newData), editor, false);
			
			System.out.println("checksum is "+checksum+" and filename is "+filename);
	        
			// Start to apply the text delta of file
			//editor.applyTextDelta(filename, "test");			
			
			editor.closeFile(filename,checksum);		
			//editor.closeDir();

		} catch (SVNException e1) {
			
			e1.printStackTrace();
		}

		
		try {

	        // Commit changes
			SVNCommitInfo info = editor.closeEdit();
			
			// Check for errors
			System.out.println(info.getErrorMessage());
	        
		} catch (SVNException e) {
			
			e.printStackTrace();
		}
		System.out.println("Exit commit()");
	}	

	public Collection<SVNLogEntry> printLog(){
		System.out.println("enter printLog");
		//String logEntry = null;
		final Collection<SVNLogEntry> logs = new LinkedList<SVNLogEntry>();
		//ISVNLogEntryHandler logHandler = null;
	
		String[] path = new String[] {""};
		
		System.out.println("before try");
		try {
			
			System.out.println("before calling log method");
			System.out.println("Path value is "+path[0]);
			repository.log(path,-1, 0, false, false,new ISVNLogEntryHandler(){
			            public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
			            	System.out.println("after in handle log entry ");
			            	
			                logs.add(logEntry);
			            }
			});
			
			System.out.println("after calling log method");
			System.out.println("Path value is "+path);
			System.out.println("Logs value is "+logs+"finished printing");
			
		} catch (SVNException e) {
			
			e.printStackTrace();
		}
		
		return logs;
	}
	
}
